package handler

import (
	"app-box/api_error"
	"app-box/models"

	"github.com/gin-gonic/gin"
)

// 自定义的handlerfunc
type HandlerFunc func(ctx Context)

/// 包装gin的Context，扩展一些工具函数
func H(handler HandlerFunc) func(*gin.Context) {
	return func(c *gin.Context) {
		var ctx = Context{Context: c}
		handler(ctx)
	}
}

type Context struct {
	*gin.Context
}

func (ctx *Context) getRequestID() string {
	return ctx.GetString("RequestID")
}

func (ctx *Context) GetToken() (token models.Token, exist bool) {
	if t, ok := ctx.Get("Token"); ok {
		if v, ok := t.(models.Token); ok {
			token = v
			exist = ok
			return
		}
	}
	exist = false
	return
}

func (ctx *Context) GetTokenOrPanic() models.Token {
	if t, ok := ctx.Get("Token"); ok {
		if v, ok := t.(models.Token); ok {
			return v
		}
	}
	if err, ok := ctx.Get("TokenError"); ok && err != nil {
		panic(err)
	}
	panic(api_error.RequireLogin())
}

func (ctx *Context) ShouldBindOrPanic(obj interface{}) {
	if err := ctx.Context.ShouldBind(obj); err != nil {
		panic(api_error.InvalidParameters(err))
	}
}

func (ctx *Context) Response(resultValue interface{}) {
	var result = models.BaseResult{Code: 200, Message: "Success!"}
	switch value := resultValue.(type) {
	case nil:
		result.Data = nil
	case api_error.ApiErrorType:
		result.SetWithApiError(value)
	case error:
		result.Code = 500
		result.Message = "Server Internal Error!"
		result.Data = nil
	default:
		result.Data = value
	}
	result.RequestID = ctx.getRequestID()
	ctx.JSON(200, result)
}

func (ctx *Context) ResponseSuccess() {
	var result = models.BaseResult{Code: 200, Message: "Success!", Data: nil}
	ctx.JSON(200, result)
}
